home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / HardwareProjects / VideoText.lha / VideoText4.2 / source / pagelist.p < prev    next >
Encoding:
Text File  |  1995-06-25  |  5.5 KB  |  168 lines

  1. UNIT pagelist; {$project vt}
  2. { Verwaltung der verketteten Seitenliste zum Programm VideoText }
  3. { Es wird darauf geachtet, daß die Auswahlzeiger <thispage> und <visblpage> }
  4. { immer einen sinnvollen Inhalt haben und daß <thispage> nur bei leerer }
  5. { Liste NIL ist. }
  6.  
  7. INTERFACE; FROM vt USES global;
  8.  
  9. PROCEDURE kill_list;
  10. PROCEDURE del_from_list(target: p_onepage);
  11. PROCEDURE ins_to_list(item: p_onepage);
  12. PROCEDURE add_to_list(item: p_onepage);
  13. FUNCTION hunt_in_list(pg,sp: Integer; exact: Boolean): p_onepage;
  14. FUNCTION next_magazine(item: p_onepage): p_onepage;
  15. FUNCTION prev_magazine(item: p_onepage): p_onepage;
  16.  
  17. { ---------------------------------------------------------------------- }
  18.  
  19. IMPLEMENTATION;
  20.  
  21. {$opt q,s+,i+ } { keine Laufzeitprüfungen außer Stack und Feldindizes }
  22.  
  23. PROCEDURE kill_list;
  24. { Alle Seiten wegwerfen. }
  25. VAR hilf: p_onepage;
  26. BEGIN
  27.   hilf := root;
  28.   WHILE root<>Nil DO BEGIN
  29.     root := root^.next;
  30.     Dispose(hilf);
  31.     hilf := root;
  32.   END;
  33.   thispage := root; visblpage := Nil;
  34. END;
  35.  
  36. PROCEDURE del_from_list{(target: p_onepage)};
  37. { Die bezeichnete Seite aus der Liste herauslösen UND löschen (Dispose). }
  38. { Falls <thispage> auf die gelöschte Seite zeigt, wird sichergestellt, daß }
  39. { <thispage> anschließend wieder auf einen sinnvollen Inhalt zeigt: }
  40. {  - auf den Nachfolger der gelöschten Seite, falls sie einen hat, sonst }
  41. {  - auf ihren Vorgänger (d. h. Listenende oder Nil) }
  42. BEGIN
  43.   IF target^.prev<>Nil THEN
  44.     target^.prev^.next := target^.next  ELSE  root := target^.next;
  45.   IF target^.next<>Nil THEN
  46.     target^.next^.prev := target^.prev;
  47.   IF target=visblpage THEN visblpage := Nil;
  48.   IF target=thispage THEN BEGIN
  49.     thispage := target^.next;
  50.     IF thispage = Nil THEN thispage := target^.prev;
  51.   END;
  52.   Dispose(target);
  53. END;
  54.  
  55. FUNCTION hunt_in_list{(pg,sp: Integer; exact: Boolean): p_onepage};
  56. { Liefert einen Zeiger auf die durch <pg>, <sp> beschriebene Seite in der }
  57. { Liste. Falls eine entsprechende Seite nicht gefunden wird, ist das }
  58. { Resultat für exact=False der nächsthöhere existierende Eintrag (bzw. das }
  59. { Listenende, wenn es keinen höheren Eintrag gibt), für exact=True einfach }
  60. { Nil. Letztere Variante funktioniert dafür auch auf unsortierten Listen, }
  61. { d. h. solchen, die mit add_to_list() statt ins_to_list() aufgebaut wurden. }
  62. VAR hilf: p_onepage;
  63. BEGIN
  64.   hilf := root;
  65.   IF hilf<>Nil THEN
  66.     IF exact THEN BEGIN
  67.       { richtige Seitennummer finden }
  68.       WHILE ((hilf^.pg<>pg) OR (hilf^.sp<>sp)) AND (hilf^.next<>Nil) DO
  69.         hilf := hilf^.next;
  70.       IF ((hilf^.pg<>pg) OR (hilf^.sp<>sp)) THEN
  71.         hilf := Nil; {=hilf^.next}
  72.     END ELSE BEGIN
  73.       { richtige oder nächsthöhere Seitennummer finden }
  74.       WHILE (hilf^.pg<pg) AND (hilf^.next<>Nil) DO
  75.         hilf := hilf^.next;
  76.       { Wenn die Seitennummer stimmt, noch die Unterseite finden }
  77.       WHILE (hilf^.pg=pg) AND (hilf^.sp<sp) AND (hilf^.next<>Nil) DO
  78.         hilf := hilf^.next;
  79.     END;
  80.   hunt_in_list := hilf;
  81. END;
  82.  
  83. PROCEDURE ins_to_list{(item: p_onepage)};
  84. { Neue Seite nach Seiten- und Unterseitennummer in die Liste einsortieren. }
  85. { Es wird *nicht* überprüft, ob bereits ein gleichartiger Eintrag existiert. }
  86. VAR hilf: p_onepage;
  87. BEGIN
  88.   IF root=Nil THEN BEGIN
  89.     root := item
  90.     item^.next := Nil;
  91.     item^.prev := Nil;
  92.   END ELSE BEGIN
  93.     hilf := hunt_in_list(item^.pg,item^.sp,False);
  94.     { hilf zeigt jetzt auf die Seite, vor der eingefügt werden sollte, bzw. }
  95.     { auf das Listenende, falls die neue Seite die höchste aller Nummern hat. }
  96.     IF (hilf^.pg>item^.pg) OR ((hilf^.pg=item^.pg) AND (hilf^.sp>item^.sp))
  97.     THEN BEGIN    { Normalfall, vor hilf einfügen }
  98.       item^.prev := hilf^.prev;
  99.       item^.next := hilf;
  100.       IF hilf^.prev<>Nil THEN hilf^.prev^.next := item  ELSE  root := item;
  101.       hilf^.prev := item;
  102.     END ELSE BEGIN    { Sonderfall, hinter hilf anhängen }
  103.       item^.prev := hilf;
  104.       item^.next := hilf^.next;
  105.       IF hilf^.next<>Nil THEN hilf^.next^.prev := item;
  106.       hilf^.next := item;
  107.     END;
  108.   END;
  109.   IF thispage=Nil THEN thispage := item;
  110. END;
  111.  
  112. PROCEDURE add_to_list{(item: p_onepage)};
  113. { Hängt eine Seite ans Ende der Liste an. }
  114. VAR hilf: p_onepage;
  115. BEGIN
  116.   IF root=Nil THEN BEGIN
  117.     root := item
  118.     item^.next := Nil;
  119.     item^.prev := Nil;
  120.   END ELSE BEGIN
  121.     hilf := root;
  122.     WHILE hilf^.next<>Nil DO
  123.       hilf := hilf^.next;
  124.     { Hinter hilf anhängen: }
  125.     hilf^.next := item;
  126.     item^.prev := hilf;
  127.     item^.next := Nil;
  128.   END;
  129.   IF thispage=Nil THEN thispage := item;
  130. END;
  131.  
  132. FUNCTION next_magazine{(item: p_onepage): p_onepage};
  133. { Erste Seite finden, die hinter <item> in der Liste steht und eine andere }
  134. { Magazinnummer trägt. Absichtlich so vorsichtig formuliert, damit das auch }
  135. { auf unsortierten Listen sinnvolle Resultate liefert. }
  136. VAR mag: integer;
  137. BEGIN
  138.   IF item<>Nil THEN BEGIN
  139.     mag := item^.pg SHR 8;
  140.     { zum nächsten Magazin vorrücken }
  141.     WHILE (item^.next<>Nil) AND (item^.pg SHR 8 = mag) DO
  142.       item := item^.next;
  143.   END;
  144.   next_magazine := item;
  145. END;
  146.  
  147. FUNCTION prev_magazine{(item: p_onepage): p_onepage};
  148. { Die in Richtung Listenanfang nächstliegende Seite, die einen Magazinanfang }
  149. { markiert und nicht <item> selbst ist. }
  150. VAR mag: integer;
  151. BEGIN
  152.   IF item<>Nil THEN IF item^.prev<>Nil THEN BEGIN
  153.     item := item^.prev;
  154.     mag := item^.pg SHR 8;
  155.     { zum vorigen Magazin }
  156.     WHILE (item^.prev<>Nil) AND (item^.pg SHR 8 = mag) DO
  157.       item := item^.prev;
  158.     { Hoppla, eins zu weit ... }
  159.     IF (item^.next<>Nil) AND (item^.pg SHR 8 <> mag) THEN
  160.       item := item^.next;
  161.   END;
  162.   prev_magazine := item;
  163. END;
  164.  
  165. BEGIN   { Intialisierungsteil }
  166.   root := Nil; thispage := Nil; visblpage := Nil;
  167. END.
  168.